//
// Created by john on 2020/9/12.
//
#include "TSocket.h"


TSocket::TSocket() {

}


void TSocket::listen(int port) {
    sock= socket(AF_INET,SOCK_STREAM,0);

    int on = 1;
    int ret = setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
    if(ret<0){
        fprintf(stderr,"error in setsockopt \n");
        throw "error in setsockopt";
    }

    sockaddr_in server_addr;
    server_addr.sin_family =    AF_INET;
    server_addr.sin_addr.s_addr= htonl(INADDR_ANY);
    server_addr.sin_port = htons(port);
    ret = bind(sock,(sockaddr *)&server_addr,sizeof(server_addr));
    if(ret<0){
        fprintf(stderr,"error in bind \n");
        throw "error in bind";
        //return false;
    }
    ret = ::listen(sock,0);
    if(ret<0){
        fprintf(stderr,"error in bind \n");
        throw "error in listen";
        //return false;
    }

}

void TSocket::start() {
    sockaddr_in from;
    socklen_t len;//无符号整型

    while (true){
        int client = accept(sock,(sockaddr *)&from, &len);
        if(client<0)
        {
            continue;
        }
        socket_client socketClient;
        socketClient.client_id =client;
        socketClient.sockaddr = from;
        socketClient.socklen=len;

        if(this->onAccept != nullptr){
            this->onAccept(1,2);
        }
        //fprintf(stderr, "get one connection:[%d]\n", client);
        std::thread t(&TSocket::th_function,this,client);
        t.detach();
        //t.join();
    }
}

void TSocket::th_function(int sock_client){

    try{
        while (true){
            char buffer[2];
            int ret = recv(sock_client,buffer,sizeof(buffer),0);
            if(ret>0)
            {
                std::cout<<buffer<<std::endl;
            }else if(ret==0){
                std::cout<<"lost connection"<<std::endl;
                break;
                //printf("lost connection , Ip = %s\n", inet_ntoa(server_in.sin_addr));
                //closesocket(sock_client);
            }else{
                std::cout<<"something wrong"<<std::endl;
                break;
                //printf("something wrong of %s\n", inet_ntoa(server_in.sin_addr));
                //closesocket(sock_client);
            }

        }
    } catch (std::exception e) {
        std::cout<<"error thread"<<std::endl;
    }




}

TSocket::~TSocket() {}

void TSocket::setOnAccept(eventAccept accept) {
    TSocket::onAccept = accept;
}

